import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

@SuppressWarnings("serial")
public class Tic extends JFrame { 
	JButton[] jb = new JButton[9];// 按钮数组构成棋盘的8个落子点 
	static final char empty = 32; // 代表空格  
	static int clicknum = 0;    // 记录单击次数，决定是走X还是走O 
    static final int INFINITY = 100;// 带标无穷值  
    static final int WIN = +INFINITY; // O获胜  
    static final int LOSE = -INFINITY; // X获胜  
    static final int DRAW = 0; // 平局   // 获胜棋盘状态  
    static final int[][] WIN_STATUS = {   
	    {0, 1, 2},   
	    {3, 4, 5},   
	    {6, 7, 8},  
	    {0, 3, 6},  
	    {1, 4, 7},  
	    {2, 5, 8},  
	    {0, 4, 8},  
	    {2, 4, 6}  
	}; 
	public Tic(){   
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
	this.setSize(400, 400); //棋盘大小 
	this.setLayout(new GridLayout(3,3));   
	this.setTitle("井字棋");   // 让窗口居中显示   
	Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); // 获取屏幕尺寸封装到screen中     
	this.setLocation((screen.height - this.getHeight())/2,(screen.width - this.getWidth())/2);  // 窗口居中   // 把按钮加入窗体   
	for(int i=0; i<9; i++){    jb[i] = new JButton("");    
	jb[i].setFont(new Font("Arial",Font.BOLD,30));    
	jb[i].addActionListener(new JBClick());// 事件监听   
	this.add(jb[i]);    }    
	this.setVisible(true);   
	}
private class JBClick implements ActionListener {
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自动生成的方法存根
		for(int i=0; i<9; i++){     
			if(e.getSource() == jb[i]){// 哪个按钮被单击     
				if(++clicknum % 2 == 0){//偶数次是X        
					jb[i].setText("X");           
					}
				else{
		           jb[i].setText("O");//奇数次是O        
		         }      jb[i].setEnabled(false);//被单击过的按钮不可用    
		         }    
			}           
		int gamestate = gameState(jb);// 调方法获取棋盘状态    // 输出棋局胜负   
		switch (gamestate) {      
		case WIN:  JOptionPane.showMessageDialog(null, "O方获胜", "提示", JOptionPane.DEFAULT_OPTION);      
		break;       
		case LOSE:  JOptionPane.showMessageDialog(null, "X方获胜", "提示", JOptionPane.DEFAULT_OPTION);      
		break;      
		case DRAW:  JOptionPane.showMessageDialog(null, "平局", "提示",JOptionPane.DEFAULT_OPTION);     
		break;     }       // 如果结束，则提示  
		if (gamestate == WIN || gamestate == LOSE || gamestate == DRAW) {      
			int over = JOptionPane       .showConfirmDialog(null, "是否再来一局？", "提示",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);      
			if (over == JOptionPane.YES_OPTION) {      
				for (int i = 0; i < 9; i++) {       
					jb[i].setText(" ");       
					jb[i].setEnabled(true);       
				}      
			} 
			else {     
				System.exit(0); // 退出游戏     
			}
		}
	}
	public int  gameState(JButton[] jb){   
		int result = 1; // 棋局状态初始值   
		boolean isFull = true;  // 棋盘是否已满    // 判断棋盘是否已满    
		for (int pos = 0; pos < 9; pos++) {    
			char chess = jb[pos].getText().charAt(0);    
			if (empty == chess) {     
				isFull = false;      
				return result; // 未满则返回，继续走棋   
				}    
			}    // 棋局已满，判定胜负         
		for(int[] status:WIN_STATUS){//遍历8中棋局获胜状态 
	   //得到某个获胜棋局状态的第一个索引的字符     
	        char chess = jb[status[0]].getText().charAt(0);    // 如果为空，说明此处未下棋子，跳出循环，找下一个状态    
	        if(chess==empty){     
		        continue;    
		    }           
	        int i;      //不为空，则看其余两子是否与其相同    
	        for(i=1; i<status.length; i++){            
		        if(jb[status[i]].getText().charAt(0)!=chess){       
			        break;  //不同则跳出循环       
			    }    
		    }           
	        if(i==status.length){ // 三子连线    
		        result = chess== 'O' ? WIN : LOSE;    
		        break;     
		    }  
	 }        
	 if (result != WIN & result != LOSE & isFull)       
	         result = DRAW;  //不输不赢且棋盘满则为平    
	 return result;   
	}
}
}